home *** CD-ROM | disk | FTP | other *** search
- /*
-
-
- Copyright (C) 1990 Texas Instruments Incorporated.
-
- Permission is granted to any individual or institution to use, copy, modify,
- and distribute this software, provided that this complete copyright and
- permission notice is maintained, intact, in all copies and supporting
- documentation.
-
- Texas Instruments Incorporated provides this software "as is" without
- express or implied warranty.
-
-
- *
- * Created: MJF 08/20/90 -- Initial design and implementation.
- *
- * The TYPE_CASE defmacro
- *
- * To use, declare:
- * #pragma defmacro TYPE_CASE "type_case" delimiter=}
- *
- * TYPECASE (generic_ptr) { case_statements }
- * case_statements = case sym_name : statements [case_statements]
- *
- * THE TYPE_CASE macro is analogous to the C++ switch statment
- * It gathers all possible cases and allows the user to symbolically
- * dispatch on the type of object represented by the case statements.
- *
- * Generic* g;
- * TYPE_CASE (g) {
- * case Vector: // If the object is a vector
- * .... // Do something for Vector
- * break;
- * case List: // If the object is a list
- * .... // Do something for List
- * break;
- * default: // Else do the rest
- * ....
- * }
- *
- * expands to:
- *
- * Generic* g;
- * static Symbol* switch_symbols_g[3] = {SYM(Vector), SYM(List), NULL};
- * switch (g->select_type_of(switch_symbols_g)) {
- * case 0: // If the object is a vector
- * .... // Do something for Vector
- * break;
- * case 1: // If the object is a list
- * .... // Do something for List
- * break;
- * default: // Else do the rest
- * ....
- * }
- *
- */
-
- #include "defmacio.h"
-
- #define MAXCASE 64
- #define MAXBUF 512
-
- typedef struct case_body {
- int default_case;
- char* body;
- } Case_Body;
-
-
- typecase(argc, argv)
- int argc;
- char* argv[];
- {
- char junk[MAXBUF];
- char c;
- char* macname; /* TYPE_CASE is the macro name */
- char* genptr; /* the name of a generic pointer */
- char* name;
- char *str1, *str2;
- Case_Body cbody[30];
- int ncases, i;
- char* syms[30]; /* Contains all symbols in TYPE_CASE */
- int nsyms;
- char body[512]; /* Contains body of each case */
- int done;
-
- if(copytoken(junk) == NULL) /* Skip macro name */
- return(1);
- macname = savestring(junk);
-
- c = skip_blanks();
- if(c != '(') {
- fprintf(stderr, "%s: '%c' found instead of '('\n", macname, c);
- return 1;
- }
-
- done = 0;
- nsyms = ncases = 0;
- name = scan_next(' ');
- c = getchar();
- if (c != ')') {
- fprintf(stderr, "%s: '%c' found instead of ')' after %s\n",
- macname, c, name);
- return 1;
- }
- genptr = savestring(name);
-
- c = skip_blanks();
- if (c != '{') {
- fprintf(stderr, "%s: '%c' found instead of '{' after %s\n",
- macname, c, genptr);
- return 1;
- }
-
- name = scan_list(' ');
-
- for (i=0;i< MAXCASE;i++) {
- str2 = body;
- if (name == NULL) return 1;
-
-
- if(!strcmp(name, "case")) { /* case Vector: */
- cbody[i].default_case = 0;
- cbody[i].body = 0;
- name = scan_next(' ');
- c = skip_blanks();
- if (c != ':') {
- fprintf(stderr, "%s: Missing ':' after '%s'\n",
- macname, name);
- return 1;
- }
- syms[nsyms++] = savestring(name);
- } else if (!strcmp(name, "default")) { /* default: */
- c = getchar();
- if (c != ':') {
- fprintf(stderr, "%s: Missing ':' after '%s'\n",
- macname, name);
- return 1;
- }
- cbody[i].default_case = 1;
- cbody[i].body = 0;
- } else {
- str1 = name;
- while (*str1 != '\0') *str2++ = *str1++;
- }
-
- /* collect body of case */
- for (;;) {
- c = getchar();
- while (!isalnum(c) && c !=EOF) {
- *str2++ = c;
- c = getchar();
- }
- if (c == EOF) { /* TYPE_CASE is done */
- done = 1;
- break;
- } else unget();
-
- name = scan_list(' ');
- if (!strcmp(name,"case") || !strcmp(name,"default")) break;
-
- str1 = name;
- while (*str1 != '\0') *str2++ = *str1++;
- }
- ncases++;
- *str2 = EOS;
- cbody[i].body = savestring(body);
- if (done) break;
- }
-
- /* expand TYPE_CASE macro*/
-
- sprintf(junk, "\n{\nstatic Symbol* switch_symbols_%s[%d] = {",
- genptr, nsyms+1);
- puts(junk); /* start of SYM list */
- for (i = 0; i < nsyms; i++) { /* output each SYM name */
- sprintf(junk,"SYM(%s),", syms[i]);
- puts(junk);
- }
- puts("NULL};\n"); /* end of SYM list */
-
- sprintf(junk, "switch(%s->select_type_of(switch_symbols_%s)) {\n",
- genptr, genptr);
- puts(junk); /* start of switch statement */
-
-
-
- for (i = 0; i< ncases; i++) { /* output body for each case */
- if (cbody[i].default_case)
- sprintf(junk, "default:", i);
- else
- sprintf(junk, "case %d:", i);
- puts(junk);
- if (cbody[i].body)
- puts(cbody[i].body);
- }
- puts ("\n} \n"); /* end of switch statement */
- free(macname);
- return 0;
- }
-
-
-
-
-